home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n20.arc / SINEWAVE.ARC / SINEWAVE.C < prev    next >
C/C++ Source or Header  |  1991-10-28  |  11KB  |  283 lines

  1. /*------------------------------------------------------
  2.    SINEWAVE.C -- Multimedia Windows Sine Wave Generator
  3.                  (c) Charles Petzold, 1991
  4.   ------------------------------------------------------*/
  5.  
  6. #include <windows.h>
  7. #include <mmsystem.h>
  8. #include <math.h>
  9. #include "sinewave.h"
  10.  
  11. #define SAMPLE_RATE     11025
  12. #define FREQ_MIN           20
  13. #define FREQ_MAX         5000
  14. #define FREQ_INIT         440
  15. #define BUFFER_SIZE      2048
  16. #define SINE_TABLE_SIZE  2048
  17. #define PI                  3.14159
  18.  
  19. #define GlobalShareAlloc(dwSize) GlobalAlloc (GHND | GMEM_SHARE, dwSize)
  20.  
  21. BOOL FAR PASCAL DlgProc (HWND, WORD, WORD, LONG) ;
  22.  
  23. static char szAppName [] = "SineWave" ;
  24.  
  25. int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
  26.                     LPSTR lpszCmdLine, int nCmdShow)
  27.      {
  28.      FARPROC lpDlgProc ;
  29.  
  30.      lpDlgProc = MakeProcInstance (DlgProc, hInstance) ;
  31.      DialogBox (hInstance, szAppName, NULL, lpDlgProc) ;
  32.      FreeProcInstance (lpDlgProc) ;
  33.  
  34.      return 0 ;
  35.      }
  36.  
  37. VOID FillBuffer (LPBYTE pBuffer, int iFreq)
  38.      {
  39.      static BOOL   bSineTableSet ;
  40.      static BYTE   bySineTable [SINE_TABLE_SIZE] ;
  41.      static DWORD  dwAngle ;
  42.      int           i ;
  43.  
  44.      if (!bSineTableSet)
  45.           {
  46.           for (i = 0 ; i < SINE_TABLE_SIZE ; i++)
  47.                bySineTable [i] = (BYTE) (127 + 127 *
  48.                                          sin (i * 2 * PI / SINE_TABLE_SIZE)) ;
  49.           bSineTableSet = TRUE ;
  50.           }
  51.  
  52.      for (i = 0 ; i < BUFFER_SIZE ; i++)
  53.           {
  54.           pBuffer [i] = bySineTable [dwAngle >> 8] ;
  55.           dwAngle += 256UL * SINE_TABLE_SIZE * iFreq / SAMPLE_RATE ;
  56.  
  57.           if (dwAngle > 256L * SINE_TABLE_SIZE)
  58.                dwAngle -= 256L * SINE_TABLE_SIZE ;
  59.           }
  60.      }
  61.  
  62. BOOL FAR PASCAL DlgProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
  63.      {
  64.      static BOOL          bShutOff, bClosing ;
  65.      static char          szOpenError[] = { "Error opening waveform audio!" } ;
  66.      static char          szMemError [] = { "Error allocating memory!" } ;
  67.      static GLOBALHANDLE  hWaveHdr, hBuffer, hBuffer2 ;
  68.      static HWAVEOUT      hWaveOut ;
  69.      static HWND          hwndScroll ;
  70.      static int           iFreq = FREQ_INIT ;
  71.      static LPBYTE        pBuffer, pBuffer2 ;
  72.      static LPWAVEHDR     pWaveHdr ;
  73.      static PCMWAVEFORMAT pcm ;
  74.      int                  iDummy ;
  75.      LPBYTE               pSwap ;
  76.  
  77.      switch (message)
  78.           {
  79.           case WM_INITDIALOG:
  80.                hwndScroll = GetDlgItem (hwnd, ID_SCROLL) ;
  81.                SetScrollRange (hwndScroll, SB_CTL, FREQ_MIN, FREQ_MAX, FALSE) ;
  82.                SetScrollPos   (hwndScroll, SB_CTL, FREQ_INIT, TRUE) ;
  83.                SetDlgItemInt  (hwnd, ID_TEXT, FREQ_INIT, FALSE) ;
  84.  
  85.                return TRUE ;
  86.  
  87.           case WM_HSCROLL:
  88.                switch (wParam)
  89.                     {
  90.                     case SB_LINEUP:    iFreq -=  1 ;  break ;
  91.                     case SB_LINEDOWN:  iFreq +=  1 ;  break ;
  92.                     case SB_PAGEUP:    iFreq /=  2 ;  break ;
  93.                     case SB_PAGEDOWN:  iFreq *=  2 ;  break ;
  94.  
  95.                     case SB_THUMBTRACK:
  96.                          iFreq = LOWORD (lParam) ;
  97.                          break ;
  98.  
  99.                     case SB_TOP:
  100.                          GetScrollRange (hwndScroll, SB_CTL, &iFreq, &iDummy) ;
  101.                          break ;
  102.  
  103.                     case SB_BOTTOM:
  104.                          GetScrollRange (hwndScroll, SB_CTL, &iDummy, &iFreq) ;
  105.                          break ;
  106.                     }
  107.  
  108.                iFreq = max (FREQ_MIN, min (FREQ_MAX, iFreq)) ;
  109.  
  110.                SetScrollPos (hwndScroll, SB_CTL, iFreq, TRUE) ;
  111.                SetDlgItemInt  (hwnd, ID_TEXT, iFreq, FALSE) ;
  112.                return TRUE ;
  113.  
  114.           case WM_COMMAND:
  115.                switch (wParam)
  116.                     {
  117.                     case ID_ONOFF:
  118.  
  119.                          if (hWaveOut == NULL)
  120.                               {
  121.                                         // Allocate header and buffer memory
  122.  
  123.                               hWaveHdr = GlobalShareAlloc (sizeof (WAVEHDR)) ;
  124.  
  125.                               if (hWaveHdr == NULL)
  126.                                    {
  127.                                    MessageBeep (MB_ICONEXCLAMATION) ;
  128.                                    MessageBox (hwnd, szMemError, szAppName,
  129.                                                MB_ICONEXCLAMATION | MB_OK) ;
  130.                                    return TRUE ;
  131.                                    }
  132.  
  133.                               hBuffer = GlobalShareAlloc (BUFFER_SIZE) ;
  134.  
  135.                               if (hBuffer == NULL)
  136.                                    {
  137.                                    GlobalFree (hWaveHdr) ;
  138.                                    MessageBeep (MB_ICONEXCLAMATION) ;
  139.                                    MessageBox (hwnd, szMemError, szAppName,
  140.                                                MB_ICONEXCLAMATION | MB_OK) ;
  141.                                    return TRUE ;
  142.                                    }
  143.  
  144.                               hBuffer2 = GlobalShareAlloc (BUFFER_SIZE) ;
  145.  
  146.                               if (hBuffer2 == NULL)
  147.                                    {
  148.                                    GlobalFree (hWaveHdr) ;
  149.                                    GlobalFree (hBuffer) ;
  150.                                    MessageBeep (MB_ICONEXCLAMATION) ;
  151.                                    MessageBox (hwnd, szMemError, szAppName,
  152.                                                MB_ICONEXCLAMATION | MB_OK) ;
  153.                                    return TRUE ;
  154.                                    }
  155.  
  156.                               pWaveHdr = (LPWAVEHDR) GlobalLock (hWaveHdr) ;
  157.                               pBuffer  = (LPBYTE)    GlobalLock (hBuffer) ;
  158.                               pBuffer2 = (LPBYTE)    GlobalLock (hBuffer2) ;
  159.                               bShutOff = FALSE ;
  160.  
  161.                                         // Open waveform audio for output
  162.  
  163.                               pcm.wf.wFormatTag      = WAVE_FORMAT_PCM ;
  164.                               pcm.wf.nChannels       = 1 ;
  165.                               pcm.wf.nSamplesPerSec  = SAMPLE_RATE ;
  166.                               pcm.wf.nAvgBytesPerSec = SAMPLE_RATE ;
  167.                               pcm.wf.nBlockAlign     = 1 ;
  168.                               pcm.wBitsPerSample     = 8 ;
  169.  
  170.                               if (waveOutOpen (&hWaveOut, 0, &pcm.wf,
  171.                                                hwnd, 0L, CALLBACK_WINDOW))
  172.                                    {
  173.                                    GlobalUnlock (hWaveHdr) ;
  174.                                    GlobalUnlock (hBuffer) ;
  175.                                    GlobalUnlock (hBuffer2) ;
  176.  
  177.                                    GlobalFree (hWaveHdr) ;
  178.                                    GlobalFree (hBuffer) ;
  179.                                    GlobalFree (hBuffer2) ;
  180.  
  181.                                    hWaveOut = NULL ;
  182.                                    MessageBeep (MB_ICONEXCLAMATION) ;
  183.                                    MessageBox (hwnd, szOpenError, szAppName,
  184.                                                MB_ICONEXCLAMATION | MB_OK) ;
  185.                                    }
  186.                               }
  187.                                         // Close waveform audio
  188.                          else
  189.                               {
  190.                               bShutOff = TRUE ;
  191.                               waveOutReset (hWaveOut) ;
  192.                               }
  193.                          return TRUE ;
  194.                     }
  195.                break ;
  196.  
  197.           case MM_WOM_OPEN:
  198.                SetDlgItemText (hwnd, ID_ONOFF, "Turn Off") ;
  199.  
  200.                FillBuffer (pBuffer, iFreq) ;
  201.  
  202.                pWaveHdr->lpData          = pBuffer ;
  203.                pWaveHdr->dwBufferLength  = BUFFER_SIZE ;
  204.                pWaveHdr->dwBytesRecorded = 0L ;
  205.                pWaveHdr->dwUser          = 0L ;
  206.                pWaveHdr->dwFlags         = 0L ;
  207.                pWaveHdr->dwLoops         = 1L ;
  208.                pWaveHdr->lpNext          = NULL ;
  209.                pWaveHdr->reserved        = 0L ;
  210.  
  211.                waveOutPrepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
  212.                waveOutWrite (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
  213.  
  214.                FillBuffer (pBuffer2, iFreq) ;
  215.                return TRUE ;
  216.  
  217.           case MM_WOM_DONE:
  218.                waveOutUnprepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
  219.  
  220.                if (bShutOff)
  221.                     {
  222.                     waveOutClose (hWaveOut) ;
  223.                     return TRUE ;
  224.                     }
  225.  
  226.                pSwap    = pBuffer ;
  227.                pBuffer  = pBuffer2 ;
  228.                pBuffer2 = pSwap ;
  229.  
  230.                pWaveHdr->lpData          = pBuffer ;
  231.                pWaveHdr->dwBufferLength  = BUFFER_SIZE ;
  232.                pWaveHdr->dwBytesRecorded = 0L ;
  233.                pWaveHdr->dwUser          = 0L ;
  234.                pWaveHdr->dwFlags         = 0L ;
  235.                pWaveHdr->dwLoops         = 1L ;
  236.                pWaveHdr->lpNext          = NULL ;
  237.                pWaveHdr->reserved        = 0L ;
  238.  
  239.                waveOutPrepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
  240.                waveOutWrite (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
  241.  
  242.                FillBuffer (pBuffer2, iFreq) ;
  243.                return TRUE ;
  244.  
  245.           case MM_WOM_CLOSE:
  246.                GlobalUnlock (hWaveHdr) ;
  247.                GlobalFree   (hWaveHdr) ;
  248.  
  249.                GlobalUnlock (hBuffer) ;
  250.                GlobalFree   (hBuffer) ;
  251.  
  252.                GlobalUnlock (hBuffer2) ;
  253.                GlobalFree   (hBuffer2) ;
  254.  
  255.                hWaveOut = NULL ;
  256.                SetDlgItemText (hwnd, ID_ONOFF, "Turn On") ;
  257.  
  258.                if (bClosing)
  259.                     EndDialog (hwnd, 0) ;
  260.  
  261.                return TRUE ;
  262.  
  263.           case WM_SYSCOMMAND:
  264.                switch (wParam)
  265.                     {
  266.                     case SC_CLOSE:
  267.                          if (hWaveOut != NULL)
  268.                               {
  269.                               bShutOff = TRUE ;
  270.                               bClosing = TRUE ;
  271.  
  272.                               waveOutReset (hWaveOut) ;
  273.                               }
  274.                          else
  275.                               EndDialog (hwnd, 0) ;
  276.  
  277.                          return TRUE ;
  278.                     }
  279.                break ;
  280.           }
  281.      return FALSE ;
  282.      }
  283.